package com.javacoo.xservice.base.utils;

import java.lang.management.ManagementFactory;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.UnknownHostException;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Random;
import java.util.ResourceBundle;
import java.util.stream.Stream;

import javax.servlet.ServletRequest;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.springframework.web.util.WebUtils;

import com.javacoo.xservice.base.BaseRequest;
import com.javacoo.xservice.base.Constants;
import com.javacoo.xservice.base.support.swaparea.SwapAreaData;
import com.javacoo.xservice.base.support.swaparea.SwapAreaUtils;

import lombok.extern.slf4j.Slf4j;

/**
 * Web层辅助类
 * <p>说明:</p>
 * <li></li>
 * @author DuanYong
 * @since 2017年2月8日下午4:42:54
 */
@Slf4j
public final class WebUtil {
    /** 请求参数属性KEY */
    public static final String BASE_REQUEST_KEY = "BASE_REQUEST";
	public static final String UNKNOWN = "unknown";
	public static final String LOCAL_IP = "127.0.0.1";
	public static final int IP_LEN = 15;
	private static final String PARAM_TOKENIZER = "&";
	private static final String PARAM_DEFINE = "=";
    private WebUtil() {
	}
    
    /**
     * 获取项目根路径
     * <p>说明:</p>
     * <li></li>
     * @param request
     * @return
     * @since 2017年2月14日上午9:43:37
     */
    public static final String getRootPath(HttpServletRequest request) {
		return request.getServletContext().getRealPath("");
	}
	/**
	 * 获取指定Cookie的值
	 * 
	 * @param request request
	 * @param cookieName cookie名字
	 * @param defaultValue 缺省值
	 * @return
	 */
	public static final String getCookieValue(HttpServletRequest request, String cookieName, String defaultValue) {
		Cookie cookie = WebUtils.getCookie(request, cookieName);
		if (cookie == null) {
			return defaultValue;
		}
		return cookie.getValue();
	}



	/**
	 * 获得国际化信息
	 * 
	 * @param key 键
	 * @param request
	 * @return
	 */
	public static final String getApplicationResource(String key, HttpServletRequest request) {
		ResourceBundle resourceBundle = ResourceBundle.getBundle("ApplicationResources", request.getLocale());
		return resourceBundle.getString(key);
	}

	/**
	 * 获得参数Map
	 *
	 * @param request
	 * @return
	 */
	public static final Map<String, Object> getParameterMap(HttpServletRequest request) {
		return WebUtils.getParametersStartingWith(request, null);
	}
	public static final Map<String, String> getObjectMap(Object object) {
		if(object instanceof String && StringUtils.isNotBlank(object.toString())){
			return FastJsonUtil.stringToCollect(object.toString());
		}else{
			return FastJsonUtil.stringToCollect(FastJsonUtil.toJSONString(object));
		}
	}
	public static final Map<String, String> getUrlMap(String queryString) {
		final Map<String, String> paramsMap = new LinkedHashMap<String, String>();
		if (StringUtils.isNotBlank(queryString) && queryString.indexOf(PARAM_DEFINE) > -1) {
			Stream.of(queryString.split(PARAM_TOKENIZER)).filter(str->str.split(PARAM_DEFINE).length == 2).forEach(str ->paramsMap.put(str.split(PARAM_DEFINE)[0], str.split(PARAM_DEFINE)[1]));
		}
		return paramsMap;
	}
	/** 获取客户端IP */
	public static final String getHost(HttpServletRequest request) {
		String ip = request.getHeader("X-Forwarded-For");
		if (StringUtils.isBlank(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
			ip = request.getHeader("Proxy-Client-IP");
		}
		if (StringUtils.isBlank(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
			ip = request.getHeader("WL-Proxy-Client-IP");
		}
		if (StringUtils.isBlank(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
			ip = request.getHeader("X-Real-IP");
		}
		if (StringUtils.isBlank(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
			ip = request.getRemoteAddr();
		}
		if (LOCAL_IP.equals(ip)) {
			InetAddress inet = null;
			try { // 根据网卡取本机配置的IP
				inet = InetAddress.getLocalHost();
			} catch (UnknownHostException e) {
				e.printStackTrace();
			}
			if(inet != null){
				ip = inet.getHostAddress();
			}
		}
		// 对于通过多个代理的情况，第一个IP为客户端真实IP,多个IP按照','分割
		
		if (ip != null && ip.length() > IP_LEN) {
			if (ip.indexOf(Constants.DOT) > 0) {
				ip = ip.substring(0, ip.indexOf(Constants.DOT));
			}
		}
		return ip;
	}
	/**
	 *  获取请求方法
	 * <p>说明:</p>
	 * <li></li>
	 * @author DuanYong
	 * @since 2019/7/9 13:26
	 * @param  request
	 * @return 请求方法
	 * @version 1.0
	 */
	public static String getMethod(HttpServletRequest request){
		String reqUrl = request.getRequestURL().toString();
		if(StringUtils.isBlank(reqUrl)){
			return "";
		}
		return reqUrl.substring(reqUrl.lastIndexOf(Constants.SLASH)+1,reqUrl.length());
	}
	/**
	 * 从ServletRequest获取请求参数对象
	 * <p>说明:</p>
	 * <li></li>
	 * @author DuanYong
	 * @param servletRequest ServletRequest
	 * @return BaseRequest 请求参数
	 * @since 2017年6月28日上午11:14:46
	 */
	public static BaseRequest getBaseRequest(ServletRequest servletRequest) {
		return (BaseRequest) servletRequest.getAttribute(BASE_REQUEST_KEY);
	}
    /**
     * 将请求参数设置到ServletRequest中
     * <p>说明:</p>
     * <li></li>
     * @author DuanYong
     * @param servletRequest ServletRequest
     * @param param 请求参数对象
     * @since 2017年6月28日上午11:15:39
     */
	public static void setBaseRequest(ServletRequest servletRequest, BaseRequest param) {
		servletRequest.setAttribute(BASE_REQUEST_KEY, param);
	}
	/**
	 * 生成交易流水号
	 * <p>说明:</p>
	 * <li>当前年月日时分秒毫秒+五位随机数 </li>
	 * @author DuanYong
	 * @return
	 * @since 2017年6月29日下午5:35:04
	 */
	public static String genTransSn() {
		Random random = new Random();  
		// 获取5位随机数  
        int rannum = (int) (random.nextDouble() * (99999 - 10000 + 1)) + 10000;
        String time = TimeUtils.getCurrentDateTime(TimeUtils.TimeFormat.LONG_DATE_PATTERN_WITH_MILSEC_NONE_ALL);
        StringBuilder sn = new StringBuilder(time);
        UuidUtils uuidUtils = new UuidUtils();
        String uuid = uuidUtils.toString();
        sn.append(uuid.substring(0, 10));
        sn.append(rannum);
        return sn.toString();
	}
	/**
	 * 获取MAC地址
	 * <p>说明:</p>
	 * <li></li>
	 * @author DuanYong
	 * @return
	 * @since 2017年9月12日下午3:41:21
	 */
	public static String getMACAddress(){  
		try{
			//获取本地IP对象 
			InetAddress ia = InetAddress.getLocalHost();
	        //获得网络接口对象（即网卡），并得到mac地址，mac地址存在于一个byte数组中。  
	        byte[] mac = NetworkInterface.getByInetAddress(ia).getHardwareAddress();  
	        //下面代码是把mac地址拼装成String  
	        StringBuffer sb = new StringBuffer();  
	        for(int i=0;i<mac.length;i++){  
	            if(i!=0){  
	                sb.append(":");  
	            }  
	            //mac[i] & 0xFF 是为了把byte转化为正整数  
	            String s = Integer.toHexString(mac[i] & 0xFF);  
	            sb.append(s.length()==1?0+s:s);  
	        }  
	        //把字符串所有小写字母改为大写成为正规的mac地址并返回  
	        return sb.toString().toUpperCase();  
		}catch(Exception ex){
			ex.printStackTrace();
		}
		return "00:00:00:00:00:00";
    }  
	public static String getPid(){
		try{
			String name = ManagementFactory.getRuntimeMXBean().getName(); 
			// get pid    
			String pid = name.split("@")[0];    
			log.info("系统pid:{}",pid);
		}catch(Exception e){
			e.printStackTrace();
            log.error("获取系统pid失败:",e);
		}
		return "";
	}
	/**
	 * @author mao.tan
	 * @description 格式化mac地址为xx-xx-xx-xx-xx-xx
	 * @param str
	 * @return
	 */
	public static String formatMac(String str){
		int interval = 2;
		String separator = "-";
        StringBuffer newstr = new StringBuffer();
        if(StringUtils.isBlank(str) || interval <=0 || StringUtils.isBlank(separator) || StringUtils.isBlank(str.replaceAll(":", "").replaceAll("-", "").trim())){
        	return null;
        }
        str = str.replaceAll(":", "").replaceAll("-", "").trim();
        int size = ((str.length()) % interval == 0) ? ((str.length()) / interval) : ((str.length()) / interval + 1);  
        for (int i = 0; i < size; i++) {  
            int endIndex = (i + 1) * interval;  
            if ((i + 1) == size) {  
                endIndex = str.length();  
            }  
            if (i == 0) {  
                newstr.append(str.substring(i, endIndex));  
            } else {  
            	newstr.append(separator).append(str.substring(i * interval, endIndex));  
            }  
        }  
        return newstr.toString().toLowerCase();  
    }
	/**
	 * 获取当前数据交换区数据
	 * <p>说明:</p>
	 * <li></li>
	 * @author DuanYong
	 * @return
	 * @since 2017年6月30日上午10:32:15
	 */
	public static SwapAreaData getSwapAreaData() {
		return SwapAreaUtils.getSwapAreaData();
	}
}
